//////////////////////////////////////////////////
// glStore.hpp
//
// Author: Tarik Belabbas et Adrien Hoffer
//////////////////////////////////////////////////

#include "../common/Common.h"

using namespace std;

//------------------------------------------------------------------------------
template < typename Type >
glStore< Type >::glStore()
{
	m_elementSize	= 0;
}

//------------------------------------------------------------------------------
template < typename Type >
glStore< Type >::~glStore()
{

}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::add1( const Type& _value )
{
	// Setting the element size if it hasn't already been set and if interlacing
	// is disabled
	if ( m_elementSize == 0 )
	{
		m_elementSize = 1;
	}

	// Checking if the store can contain interlaced attributes or attributes
	// composed of one value
	if ( ( m_elementSize == -1 ) || ( m_elementSize == 1 ) )
	{
		m_store.push_back( _value );
	}
	else
	{
		ST_WARNING( ( "Invalid m_elementSize value." ) );
	}
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::add2( const Type& _sValue, const Type& _tValue )
{
	// Setting the element size if it hasn't already been set and if interlacing
	// is disabled
	if ( m_elementSize == 0 )
	{
		m_elementSize = 2;
	}

	// Checking if the store can contain interlaced attributes or attributes
	// composed of two values
	if ( ( m_elementSize == -1 ) || ( m_elementSize == 2 ) )
	{
		m_store.push_back( _sValue );
		m_store.push_back( _tValue );
	}
	else
	{
		ST_WARNING( ( "Invalid m_elementSize value." ) );
	}
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::add3( const Type& _xCoord, const Type& _yCoord,
		const Type& _zCoord )
{
	// Setting the element size if it hasn't already been set and if interlacing
	// is disabled
	if ( m_elementSize == 0 )
	{
		m_elementSize = 3;
	}

	// Checking if the store can contain interlaced attributes or attributes
	// composed of three values
	if ( ( m_elementSize == -1 ) || ( m_elementSize == 3 ) )
	{
		m_store.push_back( _xCoord );
		m_store.push_back( _yCoord );
		m_store.push_back( _zCoord );
	}
	else
	{
		ST_WARNING( ( "Invalid m_elementSize value." ) );
	}
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::add4( const Type& _red, const Type& _green,
		const Type& _blue, const Type& _alpha )
{
	// Setting the element size if it hasn't already been set and if interlacing
	// is disabled
	if ( m_elementSize == 0 )
	{
		m_elementSize = 4;
	}

	// Checking if the store can contain interlaced attributes or attributes
	// composed of four values
	if ( ( m_elementSize == -1 ) || ( m_elementSize == 4 ) )
	{
		m_store.push_back( _red );
		m_store.push_back( _green );
		m_store.push_back( _blue );
		m_store.push_back( _alpha );
	}
	else
	{
		ST_WARNING( ( "Invalid m_elementSize value." ) );
	}
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::setElementSize( int _elementSize )
{
	ST_ASSERT( ( _elementSize > 0 ), ( "Invalid _elementSize parameter, %d", _elementSize ) );

	m_elementSize = _elementSize;
}

//------------------------------------------------------------------------------
template < typename Type >
unsigned int glStore< Type >::getNbElements() const
{
	if ( ( m_elementSize == 0 ) || ( m_elementSize == -1 ) )
	{
		return 0;
	}
	else
	{
		return m_store.size() / m_elementSize;
	}
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::reserve( int _capacity )
{
	ST_ASSERT( ( _capacity > 0 ), ( "Invalid _capacity parameter, %d", _capacity ) );

	m_store.reserve( _capacity );
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::resize( int _size, const Type& _object )
{
	ST_ASSERT( ( _size > 0 ), ( "Invalid _size parameter, %d", _size ) );

	m_store.resize( _size, _object );
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::setInterlacing( bool _interlacing )
{
	if ( _interlacing )
	{
		m_elementSize = -1;
	}
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::clear()
{
	m_store.clear();
	m_elementSize = 0;
}

//------------------------------------------------------------------------------
template < typename Type >
void glStore< Type >::printStore()
{
	ST_LOG( ( "Printing store content:" ) );
	for ( typename vector< Type >::iterator it = m_store.begin(); it != m_store.end(); ++it )
	{
		ST_LOG( ( "Index %d = %f", it - m_store.begin(), *it ) );
	}
}
